package main

import (
	"fmt"
)

type empty_int interface {
}

type Shaper interface {
	Area() float64
}
type Square struct {
	length float64
}

func (s Square) Area() float64 {
	return s.length * s.length
}

type Circle struct {
	radius float64
}

func (c *Circle) Area() float64 {
	return 3.14 * c.radius * c.radius
}

func main() {
	any := make([]interface{}, 5)
	any[0] = 11
	any[1] = "hello world"
	any[2] = []int{11, 22, 33, 44, 55}
	for _, value := range any {
		fmt.Println(value)
	}

	testSlice := []int{11, 22, 33, 44}
	var newSlice []int

	//拷贝成功
	newSlice = testSlice
	fmt.Println(newSlice)
	//拷贝失败
	//原因：普通的slice 它的每个元素都是int类型，int类型的内存布局和空接口不一样
	//对象内存布局在编译时间已经确定好了，所以没法直接将不同的内存的数据结构进行拷贝
	//要完成期待的拷贝，可以使用fo-range的方式，将slice里的每个元素赋值给空接口的元素，也就是一个个空接口的元素
	//	var any []interface{}
	//	any = testSlice
	//	fmt.Println(any)

	var anys []interface{}
	fmt.Printf("拷贝前：%v \n", anys)
	for _, value := range testSlice {
		anys = append(anys, value)
	}
	fmt.Printf("拷贝后：%v \n", anys)

	var ins1, ins2 Shaper

	//指针类型
	s1 := new(Square)
	s1.length = 3.0
	ins1 = s1

	if v, ok := ins1.(*Square); ok {
		fmt.Printf("ins1: %T\n", v)
	}
	//值类型
	s2 := Square{4.0}
	ins2 = s2
	if v, ok := ins2.(Square); ok {
		fmt.Printf("ins2: %T\n", v)
	}

	s3 := &Square{3.3}
	whichType(s3)

	s4 := Square{3.4}
	whichType(s4)

	c1 := new(Circle)
	c1.radius = 2.3
	whichType(c1)

}

func whichType(n Shaper) {
	switch v := n.(type) {
	case *Square:
		fmt.Printf("Type *Square %T\n", v)
	case Square:
		fmt.Printf("Type Square %T\n", v)
	case *Circle:
		fmt.Printf("Type Circle %T\n", v)

	case nil:
		fmt.Printf("nil value: nothing to check?")
	default:
		fmt.Printf("Unexpected  Type %T\n", v)
	}
}
